The Growing Esports Industry

The first competitive games started on arcade machines in the late 1970s with Space Invader and Twin Galaxies where the professional players strive to beat each other’s record to become the world record holder. In the 1980s, more games were released that many of us know today like Pac-Man. A shift from arcades to gaming consoles occurred with the release of Nintendo systems. The new popularized way of gaming was becoming more accessible to the average consumer than ever before. As Nintendo continued to grow through the 1990s, the fast advancing computer technology became a new and different mode of gaming with personal computers.

1980s competitve games

The large amount of competitive users led to organized competitions where tens of millions of fans of the top games follow these matches allowing the game companies to profit. Eventually these competitive matches transformed into a sport known as Esports. Many of the top games help create and influence the start of Esports teams and organizations made of world-class gamers. In total, hundreds of millions of US dollars are profitted from the Esports industries just through professional tournament prize earnings.

As seen above, in late 1990s to the late 2010s there was a exponential growth in the tournaments’ prize earnings from all Esports teams, orgnaizations, and all variety of competitive. In fact the earnings from tournaments in the last 3 years totals to more than the 20 years before! Unfortunately for the Esports industry in 2020, the toll of the COVID-19 pandemic is evident where large gatherings were impossible to view the professional matches. The canceled tournaments destroyed the potential of growth of Esports although some game companies like Riot Games worked with the teams to provide a remote competitive experience and a fair tournament to take place (more on this later).

These Esports organizations are created with a focus on a specific game and eventually grow from tournament prizes to create different teams for different competitive games. Turning a team into an organization.

The bargraph above shows the top Esports organzations/teams around the world with teams that have contracted professional players who competed in professional matches and earn the tournaments prizes. One of the games that provide one the largest percent of the organization’s total earnings is League of Legends.

Of the top four Esports teams that have earned the majority of their prize from professional tournaments from League of Legends, the three teams, SK Telecom T1, Invictus Gaming, and Fnatic, have all won the international League of Legends Worlds tournament that provides a large monetary prize. League of legends have impacted the massive growth of the largest Esports teams in the world.

What is League of Legends?

Map of League of Legends - Summoner’s Rift

But before we can discuss the impact of League of Legends, it is good to know what the praise and large following of the game is about. Created in 2009, League legends is a team multiplayer online battle arena where the two teams made of 5 players where the goal is to defeat the enemies’ “nexus” or their base located on opposite sides of the map. The map, called "Summoner’s Rift, is split by three lanes lined with three turrets in each lane and two more turrets protecting the nexus for each side of the map. In between each lane is an area known as the jungle where jungle monsters (raptors, krugs, wolves, gromp, golem, blue sentinel, and red brambleback) reside. There is also a river that runs across the map with pits home to the Rift Herald, Baron Nashor, Elemental Dragons, and Elder Dragon.

Each team chooses a champion that spawn on the map that have with an assigned role: top lane, mid lane, bot lane, support (also in the bot lane), and jungler. Based of the name of their roles, they will play the game in those respective locations. When the game starts, the lane players (also called laners) meet each other in their lane with a small group of minions that continuously spawn and walk from the nexus down to their respective lanes, while the jungler traverses through the jungle. In each lane, the laner’s goal is to kill the minions for earning in game gold and also attempt to kill the opposing enemy laner which also grants them a significant amount more gold. The junglers also earn in game gold by killing the jungler monsters or visiting a lane to help their teammate kill the enemy. This process of killing minions, monsters, and enemy players goes on as each player accumulates gold in order to purchase specialized items to increase the strength, health, and abilities of each player’s champion. The stronger the champion becomes the higher the chance the team can kill the enemies and push towards their base to destroy the nexus and win the match.

What factor(s) determines which League of Legends team will win?

The methods to wina match becomes much more complicated when professional players and teams consider the smallest details, stats, and actions. A small mistake by buying the wrong in game item or walking to the wrong area and getting ambushed by the enemy can turn the game around towards the team that would seem to be losing. But what statistics will majorly determines the likelihood the team will win?

Before I can answer this question, I will explain what the data is collected on. In multiplayer League of Legends, there are two main gamemodes on Summoner’s Rift: Normal and Ranked. The difference between the two gamemodes is Ranked gives the players a tier from Iron to Challenger where the players can climb the tier ladder by earning “LP” points based off each game they win or lose. Another thing to note is when a player queues up for a game match on the Summoner’s Rift map they will spawn on the right side nexus or the left side nexus where right is blue side and left is red side.

The graph above shows the data collected from over 9,800 Diamond ranked games from the Western European server. The focus of this specific analysis for League of Legends shows that among the many variables inside the game over 70% of the games a team wins by non-professional players are greatly impacted by the positive gold difference relative to the opposing team where the gold is earned by farming minions and jungle monsters, killing the enemy, and accomplishing the objectives that give gold.

Ranks from left to right: Iron, Bronze, Silver, Gold, Platinum, Diamond, Master, Grandmaster, Challenger

Other factors that lead to the result of the game that are less related (although partially involve gold gains for the team) are objectives. In the game on Summoner’s Rift there are certain objectives to help the team pull ahead to reach the final goal of destroying the nexus. The following is a general list of objectives that the team can achieve located in the pits around the river of the map:

  • Rift Herald: killing this creature gives the player a drop that can be used to spawned the Herald to act as a battering ram against turrets and other enemy structures that will grant gold to the players

  • Elemental Dragons: There are four elemental dragons that the players can kill that will grant the entire team a buff (an increased in a certain stat) based on which elemental dragon is slain

  • Baron Nashor: A giant serpent-like creature that when killed grants each player 300 gold on the team. Also gives them power of strengthen the ally minions when the payer is close enough to the minions.

  • Elder Dragon: killing the Elder dragon grants the team 250 gold and strongest individual buff to each player that lasts for a short time.

  • Structures Destroyed: Number of turrets a team destroys (out of the 11 total) to get to the enemies’ nexus

For each objective that the team achieves within a match from the list above, one objective point is given to the blue/red team. The graph above shows how completing objectives can result in a win. Matches labeled “Expected” means a team’s objective score is higher than the other team and the final result is the team with the higher score won. Matches labeled “Undefined” means the objective score for both teams are equal so the result of the match depends on other factors. Matches labeled "Unexpected means a team’s objective score is lower than the other team and the final result is the team with the lower score won. Over 60% of the matches in over 9800 Diamond ranked games show that not completing as much objectives or only completing equal amount of objectives as the enemy team can still result in a victory.

So what does all this data mean for the average League of legends? In order for you to have the best chance possible to win the game, it is extremely important to farm minions and kill jungle monsters to have the safest path towards earning the most gold without dying by the enemy and winning a game.

Professional League of Legends Esports

As mentioned before the ranking system of League of Legends helps determine the knowledge and skill level of a player. Since League of Legends is an international game, each region of the world is dedicated a server for the players to play on. Each regional server ranks the players with accounts specifically dedicated to that server. The largest servers that will de analyzed is North American, Chinese, Korean, and European. The professional leagues named LCS, LPL, LCK, and LEC respectively to each large League of Legends server. Each professional league have 10 to 17 teams that compete within their own region for a championship title. This professional system has two rounds of competition for a regional title where each round is called “Spring Split” and “Summer Split”. Below is the overall winrate of each team in each region for both Spring and Summer Splits.

The methods and data previously used in “What is League of Legends?” was to predict the outcomes of of non-professional games. Players signed to professional League of Legends teams and organizations are extremely higher skilled compare to the Diamond ranked players. But does these player’s skill level change the same conclusion that earning the most gold and not completing more objectives than the opposing team still lead to a victory?

Interestingly, of the 1500 professional games played this year i the four regions over 98% percent of each color team with a positive gold differential resulted in a victory compared to the only over 70% in non-professional ranked games. For the next factors that was analyzed to predict result of a match in a non-professional game, objective scores, the same categories of Herald, Elemental Dragons, Elder Dragon, Baron Nashor, and Structures Destroyed were used to calculate and objective score for each team in a game.

As seen in the comparing bar graph above, professional teams with a higher objective score will likely result in a victory. This result contrast the games in regular ranked games. Over 90% of the games in professional league with higher objective scores result in a victory where only about 40% of the game in non-professional matches with higher objective scores resulted in a victory. A highly possible explanation for this is in professional games the players on the same team can communicate and talk to each other to make the correct plays to achieve objectives while non-professional games are usually played with random players in their region that they most likely will not know.

By analyzing and determining which factors best helps win a match of league of legends, newer and smaller teams can come into the big scene of professional Esports and create more competition that will push each team to innovate and become better.

Why is this game imapctful to Esports?

As the 4th largest competitive game in the world, League of Legends influence and following base has played a huge part in developing the Esports industry. Besides the growing number of teams of professional and even casual players, League of Legends can influence the industry through other ways like social media influencers and streamers play the game and sparking their followers interest to join a competitive game of League of Legends.

On one of the biggest streaming platforms in the world, Twitch, League of legends is consistently ranked the one o the top most streamed and viewed games for each month in each year since 2016 as seen in the tbale below. Because the COVID-19 pandemic caused many to stay home and find entertainment online, the growth of Twitch League of Legends stream watch times have increased along with stream time.

Most Popular Streamed Games on Twitch for Each Month Each Year
Game Year Month Hours Streamed Hours Watched
League of Legends 2016 1 1362044 94377226
League of Legends 2016 2 1266715 93154772
League of Legends 2016 3 1264029 94514511
League of Legends 2016 4 1217250 88389049
League of Legends 2016 5 1196096 80679320
League of Legends 2016 6 1037242 81348505
League of Legends 2016 7 1004238 77871713
League of Legends 2016 8 1097258 81684707
League of Legends 2016 9 1087244 81064642
League of Legends 2016 10 1155966 104305242
League of Legends 2016 11 1127714 76730765
League of Legends 2016 12 1241696 81349398
League of Legends 2017 1 1363324 99332369
League of Legends 2017 2 1209135 99415477
League of Legends 2017 3 1189566 90835130
League of Legends 2017 4 1179314 82852693
League of Legends 2017 5 1231374 87929525
League of Legends 2017 6 1149523 84467396
League of Legends 2017 7 1301262 84734733
PLAYERUNKNOWN'S BATTLEGROUNDS 2017 8 1970087 73809309
League of Legends 2017 9 1229324 74422199
League of Legends 2017 10 1322094 94680105
League of Legends 2017 11 1342443 82917485
League of Legends 2017 12 1385791 68756773
League of Legends 2018 1 1774648 89024896
League of Legends 2018 2 1565610 81115898
Fortnite 2018 3 6062527 118391174
Fortnite 2018 4 7309656 128654925
Fortnite 2018 5 7645739 144602326
Fortnite 2018 6 6797681 126859989
Fortnite 2018 7 8073931 152086231
Fortnite 2018 8 8166820 131436549
Fortnite 2018 9 7407787 106325201
Fortnite 2018 10 6638650 112125020
Fortnite 2018 11 6629217 107793716
Fortnite 2018 12 9027163 118143183
Fortnite 2019 1 10205058 126502656
Apex Legends 2019 2 5580337 123090969
League of Legends 2019 3 1966064 108481064
Fortnite 2019 4 7536634 100443090
Fortnite 2019 5 6801136 107228121
Fortnite 2019 6 5793509 92750132
Fortnite 2019 7 5704941 90508922
Fortnite 2019 8 5436945 89053008
World of Warcraft 2019 9 2264059 89821179
League of Legends 2019 10 2204626 125658644
League of Legends 2019 11 2126093 95436703
Just Chatting 2019 12 1265051 83590066
League of Legends 2020 1 2953365 99657869
League of Legends 2020 2 2549292 121635889
League of Legends 2020 3 3062720 123599885
VALORANT 2020 4 4588347 344551979
Just Chatting 2020 5 2602630 181536582
Just Chatting 2020 6 2438913 174681829
Just Chatting 2020 7 2582898 182688702
Just Chatting 2020 8 2607784 170478547
Just Chatting 2020 9 2550812 168706952
Just Chatting 2020 10 2757457 203159545

League of Legends have created a unique community through followings from non-professional players, professional teams, and streamers/social media influencers that ultimately help shape and provide growth to the large and expanding Esports industry.

Data Collection

The datasets used in this project majorly from kaggle.com, EsportsEarnings.com, and Riot Games (Creator and owner of League of Legends). Below are link to the websites to the data.

Esports Earnings

League of Legends Game Statistics

Non-Professional Games: - https://www.kaggle.com/bobbyscience/league-of-legends-diamond-ranked-games-10-min

Professional: - https://www.kaggle.com/xmorra/lol2020esports?select=matches2020.csv - https://www.kaggle.com/fernandorubiogarcia/2020-league-of-legends-competitive-games

Streams - Twitch

LS0tDQp0aXRsZTogIkVzcG9ydHM6IExlYWd1ZSBvZiBMZWdlbmRzIg0KYXV0aG9yOiAiKkNoYXJsaWUgVHJhbioiDQpkYXRlOiAiMTIvMTgvMjAyMCINCm91dHB1dDogDQogIGh0bWxfZG9jdW1lbnQ6DQogICAga2VlcF9tZDogVFJVRQ0KICAgIHRvYzogVFJVRQ0KICAgIHRvY19mbG9hdDogVFJVRQ0KICAgIGRmX3ByaW50OiBwYWdlZA0KICAgIGNvZGVfZG93bmxvYWQ6IHRydWUNCiAgICB0aGVtZTogdW5pdGVkDQogIA0KLS0tDQoNCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsIGVycm9yPVRSVUUsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UpDQpgYGANCg0KYGBge3IgbGlicmFyaWVzLCBlY2hvPUZBTFNFfQ0KbGlicmFyeSh0aWR5dmVyc2UpICAgICAjIGZvciBkYXRhIGNsZWFuaW5nIGFuZCBwbG90dGluZw0KbGlicmFyeShsdWJyaWRhdGUpICAgICAjIGZvciBkYXRlIG1hbmlwdWxhdGlvbg0KbGlicmFyeShnZ3RoZW1lcykgICAgICAjIGZvciBtb3JlIHRoZW1lcyAoaW5jbHVkaW5nIHRoZW1lX21hcCgpKQ0KbGlicmFyeShnZ2FuaW1hdGUpICAgICAjIGZvciBhZGRpbmcgYW5pbWF0aW9uIGxheWVycyB0byBnZ3Bsb3RzDQpsaWJyYXJ5KGdpZnNraSkgICAgICAgICMgZm9yIGNyZWF0aW5nIHRoZSBnaWYgKGRvbid0IG5lZWQgdG8gbG9hZCB0aGlzIGxpYnJhcnkgZXZlcnkgdGltZSxidXQgbmVlZCBpdCBpbnN0YWxsZWQpDQpsaWJyYXJ5KHRyYW5zZm9ybXIpICAgICMgZm9yICJ0d2VlbmluZyIgKGdnYW5pbWF0ZSkNCmxpYnJhcnkocGF0Y2h3b3JrKSAgICAgIyBmb3IgbmljZWx5IGNvbWJpbmluZyBnZ3Bsb3QyIGdyYXBocyAgDQpsaWJyYXJ5KGd0KSAgICAgICAgICAgICMgZm9yIGNyZWF0aW5nIG5pY2UgdGFibGVzDQpsaWJyYXJ5KHN0cmluZ3IpICAgICAgICMgZm9yIHN0cmluZyBjb252ZXJzaW9ucw0KbGlicmFyeShnZ2ltYWdlKSAgICAgICAjIGZvciByZWFkaW5nIGluIGltYWdlcw0KbGlicmFyeShwbmcpDQpgYGANCg0KYGBge3IgZGF0YSwgZWNobyA9IEZBTFNFfQ0KR2VuZXJhbEVzcG9ydERhdGEgPC0gcmVhZC5jc3YoIkdlbmVyYWxFc3BvcnREYXRhLmNzdiIpDQoNCkhpc3RvcmljYWxFc3BvcnREYXRhIDwtIHJlYWQuY3N2KCJIaXN0b3JpY2FsRXNwb3J0RGF0YS5jc3YiKSAlPiUgDQogIG11dGF0ZShEYXRlID0gZG15KERhdGUpKSAlPiUgDQogIG11dGF0ZSh5ZWFyID0geWVhcihEYXRlKSkNCg0KaGlnaF9kaWFtb25kX3JhbmtlZF8xMG1pbiA8LSByZWFkLmNzdigiaGlnaF9kaWFtb25kX3JhbmtlZF8xMG1pbi5jc3YiKQ0KDQp0d2l0Y2hkYXRhIDwtIHJlYWQuY3N2KCJ0d2l0Y2hkYXRhLmNzdiIpDQoNCnByb19sb2xfbWF0Y2hlcyA8LSByZWFkLmNzdigibWF0Y2hlczIwMjAuY3N2IikNCg0KdGVhbV9lYXJuaW5ncyA8LSByZWFkLmNzdigiZWUuY3N2IikNCg0KbG9sX3RvdXJuYW1lbnRfZWFybmluZ3MgPC0gcmVhZC5jc3YoImxvbGVhcm5pbmdzYnl0ZWFtLmNzdiIpDQoNCnByb19pbmRlcHRoX3N0YXRzIDwtIHJlYWQuY3N2KCIwOF8xOV8yMDIwLmNzdiIpICU+JSANCiAgZmlsdGVyKGxlYWd1ZSAlaW4lIGMoIkxQTCIsICJMQ1MiLCAiTENLIiwgIkxFQyIpKSAlPiUgDQogIHNlbGVjdChjKCJsZWFndWUiLCAicGF0Y2giLCBlbmRzX3dpdGgoYygiZHJhZ29ucyIsICJlbGRlcnMiLCAiaGVyYWxkcyIsICJiYXJvbnMiLCAidG93ZXJzIiwgImluaGliaXRvcnMiLCAidG90YWxnb2xkIiwgInJlc3VsdCIpKSkpICU+JSANCiAgYXJyYW5nZShsZWFndWUpICU+JSANCiAgbXV0YXRlX2FsbCh+cmVwbGFjZSguLCBpcy5uYSguKSwgMCkpDQogIA0KdHdpdGNoX2dhbWVzIDwtIHJlYWQuY3N2KCJUd2l0Y2hfZ2FtZV9kYXRhLmNzdiIpICU+JSANCiAgbXV0YXRlKERhdGUgPSBkbXkoRGF0ZSkpDQpgYGANCg0KIyMgVGhlIEdyb3dpbmcgRXNwb3J0cyBJbmR1c3RyeQ0KICANCiAgDQpUaGUgZmlyc3QgY29tcGV0aXRpdmUgZ2FtZXMgc3RhcnRlZCBvbiBhcmNhZGUgbWFjaGluZXMgaW4gdGhlIGxhdGUgMTk3MHMgd2l0aCBTcGFjZSBJbnZhZGVyIGFuZCBUd2luIEdhbGF4aWVzIHdoZXJlIHRoZSBwcm9mZXNzaW9uYWwgcGxheWVycyBzdHJpdmUgdG8gYmVhdCBlYWNoIG90aGVyJ3MgcmVjb3JkIHRvIGJlY29tZSB0aGUgd29ybGQgcmVjb3JkIGhvbGRlci4gSW4gdGhlIDE5ODBzLCBtb3JlIGdhbWVzIHdlcmUgcmVsZWFzZWQgdGhhdCBtYW55IG9mIHVzIGtub3cgdG9kYXkgbGlrZSBQYWMtTWFuLiBBIHNoaWZ0IGZyb20gYXJjYWRlcyB0byBnYW1pbmcgY29uc29sZXMgb2NjdXJyZWQgd2l0aCB0aGUgcmVsZWFzZSBvZiBOaW50ZW5kbyBzeXN0ZW1zLiBUaGUgbmV3IHBvcHVsYXJpemVkIHdheSBvZiBnYW1pbmcgd2FzIGJlY29taW5nIG1vcmUgYWNjZXNzaWJsZSB0byB0aGUgYXZlcmFnZSBjb25zdW1lciB0aGFuIGV2ZXIgYmVmb3JlLiBBcyBOaW50ZW5kbyBjb250aW51ZWQgdG8gZ3JvdyB0aHJvdWdoIHRoZSAxOTkwcywgdGhlIGZhc3QgYWR2YW5jaW5nIGNvbXB1dGVyIHRlY2hub2xvZ3kgYmVjYW1lIGEgbmV3IGFuZCBkaWZmZXJlbnQgbW9kZSBvZiBnYW1pbmcgd2l0aCBwZXJzb25hbCBjb21wdXRlcnMuIA0KDQoNCiFbMTk4MHMgY29tcGV0aXR2ZSBnYW1lc10oMTk4MHNnYW1lc3BpY3R1cmUucG5nKQ0KDQoNClRoZSBsYXJnZSBhbW91bnQgb2YgY29tcGV0aXRpdmUgdXNlcnMgbGVkIHRvIG9yZ2FuaXplZCBjb21wZXRpdGlvbnMgd2hlcmUgdGVucyBvZiBtaWxsaW9ucyBvZiBmYW5zIG9mIHRoZSB0b3AgZ2FtZXMgZm9sbG93IHRoZXNlIG1hdGNoZXMgYWxsb3dpbmcgdGhlIGdhbWUgY29tcGFuaWVzIHRvIHByb2ZpdC4gRXZlbnR1YWxseSB0aGVzZSBjb21wZXRpdGl2ZSBtYXRjaGVzIHRyYW5zZm9ybWVkIGludG8gYSBzcG9ydCBrbm93biBhcyBFc3BvcnRzLiBNYW55IG9mIHRoZSB0b3AgZ2FtZXMgaGVscCBjcmVhdGUgYW5kIGluZmx1ZW5jZSB0aGUgc3RhcnQgb2YgRXNwb3J0cyB0ZWFtcyBhbmQgb3JnYW5pemF0aW9ucyBtYWRlIG9mIHdvcmxkLWNsYXNzIGdhbWVycy4gSW4gdG90YWwsIGh1bmRyZWRzIG9mIG1pbGxpb25zIG9mIFVTIGRvbGxhcnMgYXJlIHByb2ZpdHRlZCBmcm9tIHRoZSBFc3BvcnRzIGluZHVzdHJpZXMganVzdCB0aHJvdWdoIHByb2Zlc3Npb25hbCB0b3VybmFtZW50IHByaXplIGVhcm5pbmdzLiANCg0KDQoNCmBgYHtyIGVjaG8gPSBGQUxTRX0NCmJhcmxpbmVncmFwaCA8LSBIaXN0b3JpY2FsRXNwb3J0RGF0YSAlPiUgDQogIGdyb3VwX2J5KHllYXIpICU+JSANCiAgc3VtbWFyaXNlKHN1bUVhcm5pbmdzID0gc3VtKEVhcm5pbmdzKS8xMDAwMDAwKSANCiAgDQogIA0KZ3Jvd3RoX3RpbWUgPC0gZ2dwbG90KGJhcmxpbmVncmFwaCwgYWVzKHggPSB5ZWFyLA0KICAgICAgICAgICAgIHkgPSBzdW1FYXJuaW5ncykpKw0KICBnZW9tX2NvbChjb2xvciA9ICJkYXJrYmx1ZSIsDQogICAgICAgICAgIGZpbGwgPSAid2hpdGUiKSsNCiAgZ2VvbV9saW5lKGNvbG9yID0gInJlZCIsDQogICAgICAgICAgICBzaXplID0gMSkrDQogIGxhYnModGl0bGUgPSAiRXNwb3J0cyBQcm9mZXNzaW9uYWwgTWF0Y2hlcyBQcml6ZSBFYXJuaW5ncyIsDQogICAgICAgc3VidGl0bGUgPSAiKE1pbGxpb25zIG9mIFVTIERvbGxhcnMpIiwNCiAgICAgICB4ID0gIiIsDQogICAgICAgeSA9ICIiLA0KICAgICAgIGNhcHRpb24gPSAiRGF0YSBmcm9tIEVzcG9ydHNFYXJuaW5ncy5jb20iKSsNCiAgdGhlbWVfbWluaW1hbCgpDQoNCnBlcnNwZWN0aXZlYmFyIDwtIEhpc3RvcmljYWxFc3BvcnREYXRhICU+JSANCiAgbXV0YXRlKGVyYSA9IGlmZWxzZSh5ZWFyID49IDE5OTggJiB5ZWFyIDw9IDIwMTcsDQogICAgICAgICAgICAgICAgICAgICAgIjE5OTggLSAyMDE3IiwNCiAgICAgICAgICAgICAgICAgICAgICAiMjAxOCAtIDIwMjAiKSkgJT4lDQogIGdyb3VwX2J5KGVyYSkgJT4lDQogIHN1bW1hcmlzZSh0b3RhbF9lYXJuaW5ncyA9IHN1bShFYXJuaW5ncykvMTAwMDAwMCkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBlcmEsDQogICAgICAgICAgICAgeSA9IHRvdGFsX2Vhcm5pbmdzLA0KICAgICAgICAgICAgIGZpbGwgPSBlcmEpKSsNCiAgZ2VvbV9jb2woKSsNCiAgbGFicyh5ID0gIiIsDQogICAgICAgeCA9ICIiLA0KICAgICAgIGNhcHRpb24gPSAiQ3JlYXRlZCBieSBDaGFybGllIFRyYW4iKSsNCiAgdGhlbWVfbWluaW1hbCgpKw0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpDQoNCmdyb3d0aF90aW1lICsgcGVyc3BlY3RpdmViYXIgDQpgYGANCg0KDQpBcyBzZWVuIGFib3ZlLCBpbiBsYXRlIDE5OTBzIHRvIHRoZSBsYXRlIDIwMTBzIHRoZXJlIHdhcyBhIGV4cG9uZW50aWFsIGdyb3d0aCBpbiB0aGUgdG91cm5hbWVudHMnIHByaXplIGVhcm5pbmdzIGZyb20gYWxsIEVzcG9ydHMgdGVhbXMsIG9yZ25haXphdGlvbnMsIGFuZCBhbGwgdmFyaWV0eSBvZiBjb21wZXRpdGl2ZS4gSW4gZmFjdCB0aGUgZWFybmluZ3MgZnJvbSB0b3VybmFtZW50cyBpbiB0aGUgbGFzdCAzIHllYXJzIHRvdGFscyB0byBtb3JlIHRoYW4gdGhlIDIwIHllYXJzIGJlZm9yZSEgVW5mb3J0dW5hdGVseSBmb3IgdGhlIEVzcG9ydHMgaW5kdXN0cnkgaW4gMjAyMCwgdGhlIHRvbGwgb2YgdGhlIENPVklELTE5IHBhbmRlbWljIGlzIGV2aWRlbnQgd2hlcmUgbGFyZ2UgZ2F0aGVyaW5ncyB3ZXJlIGltcG9zc2libGUgdG8gdmlldyB0aGUgcHJvZmVzc2lvbmFsIG1hdGNoZXMuIFRoZSBjYW5jZWxlZCB0b3VybmFtZW50cyBkZXN0cm95ZWQgdGhlIHBvdGVudGlhbCBvZiBncm93dGggb2YgRXNwb3J0cyBhbHRob3VnaCBzb21lIGdhbWUgY29tcGFuaWVzIGxpa2UgUmlvdCBHYW1lcyB3b3JrZWQgd2l0aCB0aGUgdGVhbXMgdG8gcHJvdmlkZSBhIHJlbW90ZSBjb21wZXRpdGl2ZSBleHBlcmllbmNlIGFuZCBhIGZhaXIgdG91cm5hbWVudCB0byB0YWtlIHBsYWNlIChtb3JlIG9uIHRoaXMgbGF0ZXIpLg0KDQpUaGVzZSBFc3BvcnRzIG9yZ2FuaXphdGlvbnMgYXJlIGNyZWF0ZWQgd2l0aCBhIGZvY3VzIG9uIGEgc3BlY2lmaWMgZ2FtZSBhbmQgZXZlbnR1YWxseSBncm93IGZyb20gdG91cm5hbWVudCBwcml6ZXMgdG8gY3JlYXRlIGRpZmZlcmVudCB0ZWFtcyBmb3IgZGlmZmVyZW50IGNvbXBldGl0aXZlIGdhbWVzLiBUdXJuaW5nIGEgdGVhbSBpbnRvIGFuIG9yZ2FuaXphdGlvbi4NCg0KDQpgYGB7ciwgZWNobz1GQUxTRX0NCnRvcF90ZWFtX2Vhcm5pbmdzIDwtIHRlYW1fZWFybmluZ3MgJT4lIA0KICBhcnJhbmdlKGRlc2MoVG90YWxVU0RQcml6ZSkpICU+JSANCiAgZmlsdGVyKFRvdGFsVVNEUHJpemUgPiA5MDAwMDAwKQ0KDQp0ZWFtbGlxdWlkIDwtICJUZWFtX0xpcXVpZGxvZ28ucG5nIg0Kb2cgPC0gIk9HX0VzcG9ydHNsb2dvLnBuZyINCmV2aWxnZW5pdXNlcyA8LSAiZWdsb2dvLnBuZyINCmZuYXRpYyA8LSAiRm5hdGljbG9nb19zcXVhcmUucG5nIg0KdmlydHVzLnBvciA8LSAiVmlydHVzLnByb2xvZ29fc3F1YXJlLnBuZyINCm5ld2JlZSA8LSAiTmV3YmVlbG9nb19zcXVhcmUucG5nIg0KdmljaWdhbWluZyA8LSAiNjAwcHgtVklDSV9HYW1pbmcucG5nIg0KdGVhbXNlY3JldCA8LSAiVGVhbV9TZWNyZXRfKFZpZXRuYW1lc2VfVGVhbSlsb2dvX3NxdWFyZS5wbmciDQppbnZpY3R1c2dhbWluZyA8LSAicG5nLXRyYW5zcGFyZW50LWRvdGEtMi1hc2lhLWNoYW1waW9uc2hpcHMtMjAxNS10aGUtaW50ZXJuYXRpb25hbC0yMDE0LWludmljdHVzLWdhbWluZy1ldmlsLWdlbml1c2VzLW90aGVycy1nYW1lLWJ1cm5pbmctbG9nby5wbmciDQpuYXR1c3ZpbmNlcmUgPC0gIk5hVmlfbG9nby5wbmciDQpsZ2RnYW1pbmcgPC0gIkxHRF9HYW1pbmdsb2dvX3NxdWFyZS5wbmciDQpjbG91ZDkgPC0gIjEyODBweC1DbG91ZDlfbG9nby5zdmcucG5nIg0Kc2t0IDwtICJTS19UZWxlY29tX1QxbG9nb19zcXVhcmUucG5nIg0Kd2luZ3NnYW1pbmcgPC0gIjYwMHB4LVdpbmdzLnBuZyINCnBhcmlzc2FpbnRnZXJtYWluIDwtICJQYXJpc19TYWludC1HZXJtYWluX2VTcG9ydHNsb2dvX3NxdWFyZS5wbmciDQpmYXplY2xhbiA8LSAiMTIwMHB4LUZhemVfQ2xhbi5wbmciDQoNCnRvcF90ZWFtX2ltYWdlcyA8LSB0aWJibGUoaW1hZ2UgPSBjKHRlYW1saXF1aWQsIG9nLCBldmlsZ2VuaXVzZXMsIGZuYXRpYywgdmlydHVzLnBvciwgbmV3YmVlLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmljaWdhbWluZywgdGVhbXNlY3JldCwgaW52aWN0dXNnYW1pbmcsIG5hdHVzdmluY2VyZSwgbGdkZ2FtaW5nLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xvdWQ5LCBza3QsIHdpbmdzZ2FtaW5nLCBwYXJpc3NhaW50Z2VybWFpbiwgZmF6ZWNsYW4pKQ0KDQp0b3BfdGVhbV9lYXJuaW5nc19pbWFnZXMgPC0gdG9wX3RlYW1fZWFybmluZ3MgJT4lIA0KICBtdXRhdGUodG9wX3RlYW1faW1hZ2VzKQ0KDQp0b3BfdGVhbV9lYXJuaW5nc19pbWFnZXMgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBUb3RhbFVTRFByaXplLzEwMDAwMDAsDQogICAgICAgICAgICAgICB5ID0gZmN0X3Jlb3JkZXIoVGVhbU5hbWUsIFRvdGFsVVNEUHJpemUpLA0KICAgICAgICAgICAgIGZpbGwgPSBUb3RhbFVTRFByaXplKSkrDQogIGdlb21fY29sKCkrDQogIGdlb21faW1hZ2UoYWVzKGltYWdlID0gaW1hZ2UpLCANCiAgICAgICAgICAgICBzaXplID0gMC4wNSkrDQogIHRoZW1lX21pbmltYWwoKSsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSsNCiAgc2NhbGVfeF9jb250aW51b3VzKCkrDQogIGxhYnModGl0bGUgPSAiVG90YWwgVG91cm5hbWVudCBFYXJuaW5ncyBieSBUZWFtIiwNCiAgICAgICBzdWJ0aXRsZSA9ICIoTWlsbGlvbnMgb2YgVVMgRG9sbGFycykiLA0KICAgICAgIHggPSAiIiwNCiAgICAgICB5ID0gIiIsDQogICAgICAgY2FwdGlvbiA9ICJEYXRhIGZyb20gRXNwb3J0c0Vhcm5pbmdzLmNvbSwgQ3JlYXRlZCBieSBDaGFybGllIFRyYW4iKQ0KYGBgDQoNCg0KVGhlIGJhcmdyYXBoIGFib3ZlIHNob3dzIHRoZSB0b3AgRXNwb3J0cyBvcmdhbnphdGlvbnMvdGVhbXMgYXJvdW5kIHRoZSB3b3JsZCB3aXRoIHRlYW1zIHRoYXQgaGF2ZSBjb250cmFjdGVkIHByb2Zlc3Npb25hbCBwbGF5ZXJzIHdobyBjb21wZXRlZCBpbiBwcm9mZXNzaW9uYWwgbWF0Y2hlcyBhbmQgZWFybiB0aGUgdG91cm5hbWVudHMgcHJpemVzLiBPbmUgb2YgdGhlIGdhbWVzIHRoYXQgcHJvdmlkZSBvbmUgdGhlIGxhcmdlc3QgcGVyY2VudCBvZiB0aGUgb3JnYW5pemF0aW9uJ3MgdG90YWwgZWFybmluZ3MgaXMgTGVhZ3VlIG9mIExlZ2VuZHMuDQoNCg0KYGBge3IgZWNobz1GQUxTRX0NCmxvbF92c190b3RhbF9lYXJuaW5ncyA8LSBsb2xfdG91cm5hbWVudF9lYXJuaW5ncyAlPiUgDQogIGZpbHRlcihUZWFtTmFtZSAlaW4lIGMoIlRlYW0gTGlxdWlkIiwgIk9HIiwgIkV2aWwgR2VuaXVzZXMiLCAiRm5hdGljIiwgIlZpcnR1cy5wcm8iLCAiTmV3YmVlIiwNCiAgICAgICAgICAgICAgICAgICAgICAgIlZpY2kgR2FtaW5nIiwgIlRlYW0gU2VjcmV0IiwgIkludmljdHVzIEdhbWluZyIsICJOYXR1cyBWaW5jZXJlIiwgIkxHRCBHYW1pbmciLA0KICAgICAgICAgICAgICAgICAgICAgICAiQ2xvdWQ5IiwgIlNLIFRlbGVjb20gVDEiLCAiV2luZ3MgR2FtaW5nIiwgIlBhcmlzIFNhaW50LUdlcm1haW4gRXNwb3J0cyIsIA0KICAgICAgICAgICAgICAgICAgICAgICAiRmF6ZSBDbGFuIikpICU+JSANCiAgbGVmdF9qb2luKHRvcF90ZWFtX2Vhcm5pbmdzLA0KICAgICAgICAgICAgYnkgPSAiVGVhbU5hbWUiKSAlPiUgDQogIHNlbGVjdCgtc3RhcnRzX3dpdGgoIlRlYW1JZCIpKSAlPiUgDQogIHNlbGVjdCgtc3RhcnRzX3dpdGgoIlRvdGFsVG91ciIpKSAlPiUgDQogIHBpdm90X2xvbmdlcihjb2xzID0gc3RhcnRzX3dpdGgoIlRvdGFsVVNEUHJpemUiKSwNCiAgICAgICAgICAgICAgIG5hbWVzX3RvID0gInZhcmlhYmxlIiwNCiAgICAgICAgICAgICAgIHZhbHVlc190byA9ICJwcml6ZV9lYXJuaW5ncyIpICU+JSANCiAgbXV0YXRlKHZhcmlhYmxlID0gaWZlbHNlKHZhcmlhYmxlID09ICJUb3RhbFVTRFByaXplLngiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICJUb3RhbCBQcml6ZWQgRWFybmVkIFxuKExlYWd1ZSBvZiBMZWdlbmRzKSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAiVG90YWwgUHJpemUgRWFybmVkIikpDQoNCnBlcmNlbnRhZ2VfbG9sX2Vhcm5pbmdzIDwtIGxvbF90b3VybmFtZW50X2Vhcm5pbmdzICU+JSANCiAgZmlsdGVyKFRlYW1OYW1lICVpbiUgYygiVGVhbSBMaXF1aWQiLCAiT0ciLCAiRXZpbCBHZW5pdXNlcyIsICJGbmF0aWMiLCAiVmlydHVzLnBybyIsICJOZXdiZWUiLA0KICAgICAgICAgICAgICAgICAgICAgICAiVmljaSBHYW1pbmciLCAiVGVhbSBTZWNyZXQiLCAiSW52aWN0dXMgR2FtaW5nIiwgIk5hdHVzIFZpbmNlcmUiLCAiTEdEIEdhbWluZyIsDQogICAgICAgICAgICAgICAgICAgICAgICJDbG91ZDkiLCAiU0sgVGVsZWNvbSBUMSIsICJXaW5ncyBHYW1pbmciLCAiUGFyaXMgU2FpbnQtR2VybWFpbiBFc3BvcnRzIiwgDQogICAgICAgICAgICAgICAgICAgICAgICJGYXplIENsYW4iKSkgJT4lIA0KICBsZWZ0X2pvaW4odG9wX3RlYW1fZWFybmluZ3MsDQogICAgICAgICAgICBieSA9ICJUZWFtTmFtZSIpICU+JSANCiAgc2VsZWN0KC1zdGFydHNfd2l0aCgiVGVhbUlkIikpICU+JSANCiAgc2VsZWN0KC1zdGFydHNfd2l0aCgiVG90YWxUb3VyIikpICU+JSANCiAgbXV0YXRlKHByb3BvcnRpb24gPSBUb3RhbFVTRFByaXplLngvVG90YWxVU0RQcml6ZS55KQ0KIA0KDQpncmFwaDMgPC0gbG9sX3ZzX3RvdGFsX2Vhcm5pbmdzICU+JQ0KICBnZ3Bsb3QoKSArDQogIGdlb21fY29sKGFlcyh4ID0gcHJpemVfZWFybmluZ3MvMTAwMDAwMCwNCiAgICAgICAgICAgICAgIHkgPSBmY3RfcmVvcmRlcihUZWFtTmFtZSwgcHJpemVfZWFybmluZ3MpKSkgKw0KICBmYWNldF9ncmlkKHZhcnModmFyaWFibGUpKSsNCiAgdGhlbWVfbWluaW1hbCgpKw0KICBsYWJzKHggPSAiTWlsbGlvbnMgb2YgVVMgRG9sbGFycyIsDQogICAgICAgeSA9ICIiKQ0KDQpncmFwaDQgPC0gcGVyY2VudGFnZV9sb2xfZWFybmluZ3MgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBmY3RfcmVvcmRlcihUZWFtTmFtZSwgcHJvcG9ydGlvbiksDQogICAgICAgICAgICAgeSA9IHByb3BvcnRpb24pKSsNCiAgZ2VvbV9jb2woKSsNCiAgdGhlbWVfbWluaW1hbCgpKw0KICBsYWJzKHRpdGxlID0gIlByb3BvcnRpb24gb2YgUHJpemUgRWFybmVkIGZyb20gXG5MZWFndWUgb2YgTGVnZW5kcyIsDQogICAgICAgeCA9ICIiLCANCiAgICAgICB5ID0gIiIpKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdD0xKSkNCg0KZ3JhcGg0ICsgZ3JhcGgzICsgbGFicyhjYXB0aW9uID0gIkRhdGEgZnJvbSBFc3BvcnRzRWFybmluZ3MuY29tLCBDcmVhdGVkIGJ5IENoYXJsaWUgVHJhbiIpDQpgYGANCg0KDQpPZiB0aGUgdG9wIGZvdXIgRXNwb3J0cyB0ZWFtcyB0aGF0IGhhdmUgZWFybmVkIHRoZSBtYWpvcml0eSBvZiB0aGVpciBwcml6ZSBmcm9tIHByb2Zlc3Npb25hbCB0b3VybmFtZW50cyBmcm9tIExlYWd1ZSBvZiBMZWdlbmRzLCB0aGUgdGhyZWUgdGVhbXMsIFNLIFRlbGVjb20gVDEsIEludmljdHVzIEdhbWluZywgYW5kIEZuYXRpYywgaGF2ZSBhbGwgd29uIHRoZSBpbnRlcm5hdGlvbmFsIExlYWd1ZSBvZiBMZWdlbmRzIFdvcmxkcyB0b3VybmFtZW50IHRoYXQgcHJvdmlkZXMgYSBsYXJnZSBtb25ldGFyeSBwcml6ZS4gTGVhZ3VlIG9mIGxlZ2VuZHMgaGF2ZSBpbXBhY3RlZCB0aGUgbWFzc2l2ZSBncm93dGggb2YgdGhlIGxhcmdlc3QgRXNwb3J0cyB0ZWFtcyBpbiB0aGUgd29ybGQuDQoNCg0KIyMgV2hhdCBpcyBMZWFndWUgb2YgTGVnZW5kcz8NCg0KDQohW01hcCBvZiBMZWFndWUgb2YgTGVnZW5kcyAtIFN1bW1vbmVyJ3MgUmlmdF0oU3VtbW9uZXInc19SaWZ0X1VwZGF0ZV9NYXAucG5nKQ0KDQoNCg0KQnV0IGJlZm9yZSB3ZSBjYW4gZGlzY3VzcyB0aGUgaW1wYWN0IG9mIExlYWd1ZSBvZiBMZWdlbmRzLCBpdCBpcyBnb29kIHRvIGtub3cgd2hhdCB0aGUgcHJhaXNlIGFuZCBsYXJnZSBmb2xsb3dpbmcgb2YgdGhlIGdhbWUgaXMgYWJvdXQuIENyZWF0ZWQgaW4gMjAwOSwgTGVhZ3VlIGxlZ2VuZHMgaXMgYSB0ZWFtIG11bHRpcGxheWVyIG9ubGluZSBiYXR0bGUgYXJlbmEgd2hlcmUgdGhlIHR3byB0ZWFtcyBtYWRlIG9mIDUgcGxheWVycyB3aGVyZSB0aGUgZ29hbCBpcyB0byBkZWZlYXQgdGhlIGVuZW1pZXMnICJuZXh1cyIgb3IgdGhlaXIgYmFzZSBsb2NhdGVkIG9uIG9wcG9zaXRlIHNpZGVzIG9mIHRoZSBtYXAuIFRoZSBtYXAsIGNhbGxlZCAiU3VtbW9uZXIncyBSaWZ0LCBpcyBzcGxpdCBieSB0aHJlZSBsYW5lcyBsaW5lZCB3aXRoIHRocmVlIHR1cnJldHMgaW4gZWFjaCBsYW5lIGFuZCB0d28gbW9yZSB0dXJyZXRzIHByb3RlY3RpbmcgdGhlIG5leHVzIGZvciBlYWNoIHNpZGUgb2YgdGhlIG1hcC4gSW4gYmV0d2VlbiBlYWNoIGxhbmUgaXMgYW4gYXJlYSBrbm93biBhcyB0aGUganVuZ2xlIHdoZXJlIGp1bmdsZSBtb25zdGVycyAocmFwdG9ycywga3J1Z3MsIHdvbHZlcywgZ3JvbXAsIGdvbGVtLCBibHVlIHNlbnRpbmVsLCBhbmQgcmVkIGJyYW1ibGViYWNrKSByZXNpZGUuIFRoZXJlIGlzIGFsc28gYSByaXZlciB0aGF0IHJ1bnMgYWNyb3NzIHRoZSBtYXAgd2l0aCBwaXRzIGhvbWUgdG8gdGhlIFJpZnQgSGVyYWxkLCBCYXJvbiBOYXNob3IsIEVsZW1lbnRhbCBEcmFnb25zLCBhbmQgRWxkZXIgRHJhZ29uLiANCg0KRWFjaCB0ZWFtIGNob29zZXMgYSBjaGFtcGlvbiB0aGF0IHNwYXduIG9uIHRoZSBtYXAgdGhhdCBoYXZlIHdpdGggYW4gYXNzaWduZWQgcm9sZTogdG9wIGxhbmUsIG1pZCBsYW5lLCBib3QgbGFuZSwgc3VwcG9ydCAoYWxzbyBpbiB0aGUgYm90IGxhbmUpLCBhbmQganVuZ2xlci4gQmFzZWQgb2YgdGhlIG5hbWUgb2YgdGhlaXIgcm9sZXMsIHRoZXkgd2lsbCBwbGF5IHRoZSBnYW1lIGluIHRob3NlIHJlc3BlY3RpdmUgbG9jYXRpb25zLiBXaGVuIHRoZSBnYW1lIHN0YXJ0cywgdGhlIGxhbmUgcGxheWVycyAoYWxzbyBjYWxsZWQgbGFuZXJzKSBtZWV0IGVhY2ggb3RoZXIgaW4gdGhlaXIgbGFuZSB3aXRoIGEgc21hbGwgZ3JvdXAgb2YgbWluaW9ucyB0aGF0IGNvbnRpbnVvdXNseSBzcGF3biBhbmQgd2FsayBmcm9tIHRoZSBuZXh1cyBkb3duIHRvIHRoZWlyIHJlc3BlY3RpdmUgbGFuZXMsIHdoaWxlIHRoZSBqdW5nbGVyIHRyYXZlcnNlcyB0aHJvdWdoIHRoZSBqdW5nbGUuIEluIGVhY2ggbGFuZSwgdGhlIGxhbmVyJ3MgZ29hbCBpcyB0byBraWxsIHRoZSBtaW5pb25zIGZvciBlYXJuaW5nIGluIGdhbWUgZ29sZCBhbmQgYWxzbyBhdHRlbXB0IHRvIGtpbGwgdGhlIG9wcG9zaW5nIGVuZW15IGxhbmVyIHdoaWNoIGFsc28gZ3JhbnRzIHRoZW0gYSBzaWduaWZpY2FudCBhbW91bnQgbW9yZSBnb2xkLiBUaGUganVuZ2xlcnMgYWxzbyBlYXJuIGluIGdhbWUgZ29sZCBieSBraWxsaW5nIHRoZSBqdW5nbGVyIG1vbnN0ZXJzIG9yIHZpc2l0aW5nIGEgbGFuZSB0byBoZWxwIHRoZWlyIHRlYW1tYXRlIGtpbGwgdGhlIGVuZW15LiBUaGlzIHByb2Nlc3Mgb2Yga2lsbGluZyBtaW5pb25zLCBtb25zdGVycywgYW5kIGVuZW15IHBsYXllcnMgZ29lcyBvbiBhcyBlYWNoIHBsYXllciBhY2N1bXVsYXRlcyBnb2xkIGluIG9yZGVyIHRvIHB1cmNoYXNlIHNwZWNpYWxpemVkIGl0ZW1zIHRvIGluY3JlYXNlIHRoZSBzdHJlbmd0aCwgaGVhbHRoLCBhbmQgYWJpbGl0aWVzIG9mIGVhY2ggcGxheWVyJ3MgY2hhbXBpb24uIFRoZSBzdHJvbmdlciB0aGUgY2hhbXBpb24gYmVjb21lcyB0aGUgaGlnaGVyIHRoZSBjaGFuY2UgdGhlIHRlYW0gY2FuIGtpbGwgdGhlIGVuZW1pZXMgYW5kIHB1c2ggdG93YXJkcyB0aGVpciBiYXNlIHRvIGRlc3Ryb3kgdGhlIG5leHVzIGFuZCB3aW4gdGhlIG1hdGNoLg0KDQoNCg0KIyMgV2hhdCBmYWN0b3IocykgZGV0ZXJtaW5lcyB3aGljaCBMZWFndWUgb2YgTGVnZW5kcyB0ZWFtIHdpbGwgd2luPw0KDQoNClRoZSBtZXRob2RzIHRvIHdpbmEgbWF0Y2ggYmVjb21lcyBtdWNoIG1vcmUgY29tcGxpY2F0ZWQgd2hlbiBwcm9mZXNzaW9uYWwgcGxheWVycyBhbmQgdGVhbXMgY29uc2lkZXIgdGhlIHNtYWxsZXN0IGRldGFpbHMsIHN0YXRzLCBhbmQgYWN0aW9ucy4gQSBzbWFsbCBtaXN0YWtlIGJ5IGJ1eWluZyB0aGUgd3JvbmcgaW4gZ2FtZSBpdGVtIG9yIHdhbGtpbmcgdG8gdGhlIHdyb25nIGFyZWEgYW5kIGdldHRpbmcgYW1idXNoZWQgYnkgdGhlIGVuZW15IGNhbiB0dXJuIHRoZSBnYW1lIGFyb3VuZCB0b3dhcmRzIHRoZSB0ZWFtIHRoYXQgd291bGQgc2VlbSB0byBiZSBsb3NpbmcuIEJ1dCB3aGF0IHN0YXRpc3RpY3Mgd2lsbCBtYWpvcmx5IGRldGVybWluZXMgdGhlIGxpa2VsaWhvb2QgdGhlIHRlYW0gd2lsbCB3aW4/DQoNCg0KYGBge3IgZWNobz1GQUxTRX0NCmxvbF9ibHVlX3NpZGUgPC0gaGlnaF9kaWFtb25kX3JhbmtlZF8xMG1pbiAlPiUgDQogIHNlbGVjdCgtc3RhcnRzX3dpdGgoInJlZCIpKQ0KDQpsb2xfcmVkX3NpZGUgPC0gaGlnaF9kaWFtb25kX3JhbmtlZF8xMG1pbiAlPiUgDQogIHNlbGVjdCgtc3RhcnRzX3dpdGgoImJsdWUiKSkNCg0KYmx1ZUdvbGREaWZmIDwtIGhpZ2hfZGlhbW9uZF9yYW5rZWRfMTBtaW4gJT4lIA0KICBhcnJhbmdlKGJsdWVHb2xkRGlmZikgJT4lICAgICAgICAgICAgIA0KICBmaWx0ZXIoYmx1ZUdvbGREaWZmID4gMCkgJT4lIA0KICBzdW1tYXJpc2UoYmx1ZXdpbnJhdGUgPSBzdW0ob25laXNibHVlV2lucykvbigpKjEwMCkNCg0KcmVkR29sZERpZmYgPC0gaGlnaF9kaWFtb25kX3JhbmtlZF8xMG1pbiAlPiUgDQogIGFycmFuZ2UocmVkR29sZERpZmYpICU+JSANCiAgZmlsdGVyKHJlZEdvbGREaWZmID4gMCkgJT4lIA0KICBzdW1tYXJpc2UocmVkd2lucmF0ZSA9ICgxLXN1bShvbmVpc2JsdWVXaW5zKS9uKCkpKjEwMCkNCg0KYmFyZ3JhcGhfZ29sZERpZmYgPC0gdGliYmxlKHNpZGUgPSBjKCJCbHVlIiwiQmx1ZSIsICJSZWQiLCAiUmVkIiksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzd2luID0gYygid2luIiwgImxvc2UiLCAid2luIiwgImxvc2UiKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aW5yYXRlID0gYXMubnVtZXJpYyhjKGJsdWVHb2xkRGlmZiwgMTAwLWJsdWVHb2xkRGlmZiwgcmVkR29sZERpZmYsIDEwMC1yZWRHb2xkRGlmZikpKQ0KDQoNCnNvbG9xX2dvbGRkaWZmIDwtIGdncGxvdChiYXJncmFwaF9nb2xkRGlmZiwgYWVzKHggPSBzaWRlLCB5ID0gd2lucmF0ZSwgZmlsbCA9IGlzd2luKSkrDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9ICdkb2RnZScpKw0KICB0aGVtZV9taW5pbWFsKCkrDQogIHNjYWxlX2ZpbGxfZGlzY3JldGUobmFtZSA9IE5VTEwsDQogICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygiTG9zZSIsICJXaW4iKSkrDQogIGxhYnModGl0bGUgPSAgIk5vbi1Qcm9mZXNzaW9uYWwgR2FtZXMgXG53aXRoIGEgUG9zaXRpdmUgR29sZCBEaWZmZXJlbmNlIiwNCiAgICAgICB4ID0gIiIsIA0KICAgICAgIHkgPSAiUGVyY2VudCBXaW5yYXRlIikNCg0Kc29sb3FfZ29sZGRpZmYNCmBgYA0KDQoNCkJlZm9yZSBJIGNhbiBhbnN3ZXIgdGhpcyBxdWVzdGlvbiwgSSB3aWxsIGV4cGxhaW4gd2hhdCB0aGUgZGF0YSBpcyBjb2xsZWN0ZWQgb24uIEluIG11bHRpcGxheWVyIExlYWd1ZSBvZiBMZWdlbmRzLCB0aGVyZSBhcmUgdHdvIG1haW4gZ2FtZW1vZGVzIG9uIFN1bW1vbmVyJ3MgUmlmdDogTm9ybWFsIGFuZCBSYW5rZWQuIFRoZSBkaWZmZXJlbmNlIGJldHdlZW4gdGhlIHR3byBnYW1lbW9kZXMgaXMgUmFua2VkIGdpdmVzIHRoZSBwbGF5ZXJzIGEgdGllciBmcm9tIElyb24gdG8gQ2hhbGxlbmdlciB3aGVyZSB0aGUgcGxheWVycyBjYW4gY2xpbWIgdGhlIHRpZXIgbGFkZGVyIGJ5IGVhcm5pbmcgIkxQIiBwb2ludHMgYmFzZWQgb2ZmIGVhY2ggZ2FtZSB0aGV5IHdpbiBvciBsb3NlLiBBbm90aGVyIHRoaW5nIHRvIG5vdGUgaXMgd2hlbiBhIHBsYXllciBxdWV1ZXMgdXAgZm9yIGEgZ2FtZSBtYXRjaCBvbiB0aGUgU3VtbW9uZXIncyBSaWZ0IG1hcCB0aGV5IHdpbGwgc3Bhd24gb24gdGhlIHJpZ2h0IHNpZGUgbmV4dXMgb3IgdGhlIGxlZnQgc2lkZSBuZXh1cyB3aGVyZSByaWdodCBpcyBibHVlIHNpZGUgYW5kIGxlZnQgaXMgcmVkIHNpZGUuDQoNClRoZSBncmFwaCBhYm92ZSBzaG93cyB0aGUgZGF0YSBjb2xsZWN0ZWQgZnJvbSBvdmVyIDksODAwIERpYW1vbmQgcmFua2VkIGdhbWVzIGZyb20gdGhlIFdlc3Rlcm4gRXVyb3BlYW4gc2VydmVyLiBUaGUgZm9jdXMgb2YgdGhpcyBzcGVjaWZpYyBhbmFseXNpcyBmb3IgTGVhZ3VlIG9mIExlZ2VuZHMgc2hvd3MgdGhhdCBhbW9uZyB0aGUgbWFueSB2YXJpYWJsZXMgaW5zaWRlIHRoZSBnYW1lIG92ZXIgNzAlIG9mIHRoZSBnYW1lcyBhIHRlYW0gd2lucyBieSBub24tcHJvZmVzc2lvbmFsIHBsYXllcnMgYXJlIGdyZWF0bHkgaW1wYWN0ZWQgYnkgdGhlIHBvc2l0aXZlIGdvbGQgZGlmZmVyZW5jZSByZWxhdGl2ZSB0byB0aGUgb3Bwb3NpbmcgdGVhbSB3aGVyZSB0aGUgZ29sZCBpcyBlYXJuZWQgYnkgZmFybWluZyBtaW5pb25zIGFuZCBqdW5nbGUgbW9uc3RlcnMsIGtpbGxpbmcgdGhlIGVuZW15LCBhbmQgYWNjb21wbGlzaGluZyB0aGUgb2JqZWN0aXZlcyB0aGF0IGdpdmUgZ29sZC4NCg0KDQohW1JhbmtzIGZyb20gbGVmdCB0byByaWdodDogSXJvbiwgQnJvbnplLCBTaWx2ZXIsIEdvbGQsIFBsYXRpbnVtLCBEaWFtb25kLCBNYXN0ZXIsIEdyYW5kbWFzdGVyLCBDaGFsbGVuZ2VyXShsb2xfZW1ibGVtc19hbmRfcG9zaXRpb25zLnBuZykNCg0KDQpPdGhlciBmYWN0b3JzIHRoYXQgbGVhZCB0byB0aGUgcmVzdWx0IG9mIHRoZSBnYW1lIHRoYXQgYXJlIGxlc3MgcmVsYXRlZCAoYWx0aG91Z2ggcGFydGlhbGx5IGludm9sdmUgZ29sZCBnYWlucyBmb3IgdGhlIHRlYW0pIGFyZSBvYmplY3RpdmVzLiBJbiB0aGUgZ2FtZSBvbiBTdW1tb25lcidzIFJpZnQgdGhlcmUgYXJlIGNlcnRhaW4gb2JqZWN0aXZlcyB0byBoZWxwIHRoZSB0ZWFtIHB1bGwgYWhlYWQgdG8gcmVhY2ggdGhlIGZpbmFsIGdvYWwgb2YgZGVzdHJveWluZyB0aGUgbmV4dXMuDQpUaGUgZm9sbG93aW5nIGlzIGEgZ2VuZXJhbCBsaXN0IG9mIG9iamVjdGl2ZXMgdGhhdCB0aGUgdGVhbSBjYW4gYWNoaWV2ZSBsb2NhdGVkIGluIHRoZSBwaXRzIGFyb3VuZCB0aGUgcml2ZXIgb2YgdGhlIG1hcDoNCg0KLSAqKlJpZnQgSGVyYWxkKio6IGtpbGxpbmcgdGhpcyBjcmVhdHVyZSBnaXZlcyB0aGUgcGxheWVyIGEgZHJvcCB0aGF0IGNhbiBiZSB1c2VkIHRvIHNwYXduZWQgdGhlIEhlcmFsZCB0byBhY3QgYXMgYSBiYXR0ZXJpbmcgcmFtIGFnYWluc3QgdHVycmV0cyBhbmQgb3RoZXIgZW5lbXkgc3RydWN0dXJlcyB0aGF0IHdpbGwgZ3JhbnQgZ29sZCB0byB0aGUgcGxheWVycw0KDQotICoqRWxlbWVudGFsIERyYWdvbnMqKjogVGhlcmUgYXJlIGZvdXIgZWxlbWVudGFsIGRyYWdvbnMgdGhhdCB0aGUgcGxheWVycyBjYW4ga2lsbCB0aGF0IHdpbGwgZ3JhbnQgdGhlIGVudGlyZSB0ZWFtIGEgYnVmZiAoYW4gaW5jcmVhc2VkIGluIGEgY2VydGFpbiBzdGF0KSBiYXNlZCBvbiB3aGljaCBlbGVtZW50YWwgZHJhZ29uIGlzIHNsYWluDQoNCi0gKipCYXJvbiBOYXNob3IqKjogQSBnaWFudCBzZXJwZW50LWxpa2UgY3JlYXR1cmUgdGhhdCB3aGVuIGtpbGxlZCBncmFudHMgZWFjaCBwbGF5ZXIgMzAwIGdvbGQgb24gdGhlIHRlYW0uIEFsc28gZ2l2ZXMgdGhlbSBwb3dlciBvZiBzdHJlbmd0aGVuIHRoZSBhbGx5IG1pbmlvbnMgd2hlbiB0aGUgcGF5ZXIgaXMgY2xvc2UgZW5vdWdoIHRvIHRoZSBtaW5pb25zLg0KDQotICoqRWxkZXIgRHJhZ29uKio6IGtpbGxpbmcgdGhlIEVsZGVyIGRyYWdvbiBncmFudHMgdGhlIHRlYW0gMjUwIGdvbGQgYW5kIHN0cm9uZ2VzdCBpbmRpdmlkdWFsIGJ1ZmYgdG8gZWFjaCBwbGF5ZXIgdGhhdCBsYXN0cyBmb3IgYSBzaG9ydCB0aW1lLg0KDQotICoqU3RydWN0dXJlcyBEZXN0cm95ZWQqKjogTnVtYmVyIG9mIHR1cnJldHMgYSB0ZWFtIGRlc3Ryb3lzIChvdXQgb2YgdGhlIDExIHRvdGFsKSB0byBnZXQgdG8gdGhlIGVuZW1pZXMnIG5leHVzDQoNCmBgYHtyIGVjaG89RkFMU0V9DQoNCmxvbF9vYmplY3RpdmVzX2xlYWRfdG93aW4gPC0gaGlnaF9kaWFtb25kX3JhbmtlZF8xMG1pbiAlPiUgDQogIHNlbGVjdChlbmRzX3dpdGgoYygiZ2FtZUlkIiwgImJsdWVXaW5zIiwgIlRvd2Vyc0Rlc3Ryb3llZCIsICJEcmFnb25zIiwgIkhlcmFsZHMiLCAiRWxpdGVNb25zdGVycyIpKSkgDQoNCmxvbF9vYmplY3RpdmVzX2xlYWRfdG93aW4gPC0gbG9sX29iamVjdGl2ZXNfbGVhZF90b3dpbiAlPiUgDQogIG11dGF0ZShvYmplY3RpdmVfc2NvcmVfYmx1ZSA9IHJvd1N1bXMobG9sX29iamVjdGl2ZXNfbGVhZF90b3dpblssIGMoMiw0LDYsOCldKSkgJT4lIA0KICBtdXRhdGUob2JqZWN0aXZlX3Njb3JlX3JlZCA9IHJvd1N1bXMobG9sX29iamVjdGl2ZXNfbGVhZF90b3dpblssIGMoMyw1LDcsOSldKSkgJT4lIA0KICBtdXRhdGUob2Jqc2NvcmVfY29tcGFyZSA9IGlmZWxzZSgob2JqZWN0aXZlX3Njb3JlX2JsdWUgPiBvYmplY3RpdmVfc2NvcmVfcmVkKSAmIG9uZWlzYmx1ZVdpbnMgPT0xLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkV4cGVjdGVkIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKChvYmplY3RpdmVfc2NvcmVfYmx1ZSA8IG9iamVjdGl2ZV9zY29yZV9yZWQpICYgb25laXNibHVlV2lucyA9PSAwLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJFeHBlY3RlZCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2Uob2JqZWN0aXZlX3Njb3JlX2JsdWUgPT0gb2JqZWN0aXZlX3Njb3JlX3JlZCwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlVuZGVmaW5lZCIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJVbmV4cGVjdGVkIikpKSkNCg0KIyBsb2xfb2JqZWN0aXZlc19sZWFkX3Rvd2luX3RhYmxlIDwtIGxvbF9vYmplY3RpdmVzX2xlYWRfdG93aW4gJT4lIA0KIyAgIG11dGF0ZShvbmVpc2JsdWVXaW5zID0gaWZlbHNlKG9uZWlzYmx1ZVdpbnMgPT0gMCwgIkxvc3MiLCAiV29uIikpICU+JSANCiMgICBzZWxlY3Qob25laXNibHVlV2lucywgb2JqZWN0aXZlX3Njb3JlX2JsdWUsIG9iamVjdGl2ZV9zY29yZV9yZWQsIG9ianNjb3JlX2NvbXBhcmUpIA0KIyANCiMgY29sbmFtZXMobG9sX29iamVjdGl2ZXNfbGVhZF90b3dpbl90YWJsZSlbMV0gPC0gIkJsdWUgVGVhbSBSZXN1bHQiDQojIGNvbG5hbWVzKGxvbF9vYmplY3RpdmVzX2xlYWRfdG93aW5fdGFibGUpWzJdIDwtICJCbHVlIFRlYW0gT2JqZWN0aXZlIFNjb3JlIg0KIyBjb2xuYW1lcyhsb2xfb2JqZWN0aXZlc19sZWFkX3Rvd2luX3RhYmxlKVszXSA8LSAiUmVkIFRlYW0gT2JqZWN0aXZlIFNjb3JlIg0KIyBjb2xuYW1lcyhsb2xfb2JqZWN0aXZlc19sZWFkX3Rvd2luX3RhYmxlKVs0XSA8LSAiUHJlZGljdGlvbiINCg0KICANCnNvbG9xX29ianNjb3JlIDwtIGdncGxvdChsb2xfb2JqZWN0aXZlc19sZWFkX3Rvd2luLCBhZXMoeCA9IG9ianNjb3JlX2NvbXBhcmUpKSsNCiAgZ2VvbV9iYXIoKSsNCiAgbGFicyh0aXRsZSA9ICJQcmVkaWN0aW9uIG9mIERpYW1vbmQgR2FtZXMgXG5HaXZlbiBPYmplY3RpdmUgU2NvcmUiLA0KICAgICAgIHggPSAiIiwNCiAgICAgICB5ID0gIk51bWJlciBvZiBHYW1lcyIpKw0KICB0aGVtZV9taW5pbWFsKCkNCg0Kc29sb3Ffb2Jqc2NvcmUNCmBgYA0KDQoNCkZvciBlYWNoIG9iamVjdGl2ZSB0aGF0IHRoZSB0ZWFtIGFjaGlldmVzIHdpdGhpbiBhIG1hdGNoIGZyb20gdGhlIGxpc3QgYWJvdmUsIG9uZSBvYmplY3RpdmUgcG9pbnQgaXMgZ2l2ZW4gdG8gdGhlIGJsdWUvcmVkIHRlYW0uIFRoZSBncmFwaCBhYm92ZSBzaG93cyBob3cgY29tcGxldGluZyBvYmplY3RpdmVzIGNhbiByZXN1bHQgaW4gYSB3aW4uIE1hdGNoZXMgbGFiZWxlZCAiRXhwZWN0ZWQiIG1lYW5zIGEgdGVhbSdzIG9iamVjdGl2ZSBzY29yZSBpcyBoaWdoZXIgdGhhbiB0aGUgb3RoZXIgdGVhbSBhbmQgdGhlIGZpbmFsIHJlc3VsdCBpcyB0aGUgdGVhbSB3aXRoIHRoZSBoaWdoZXIgc2NvcmUgd29uLiBNYXRjaGVzIGxhYmVsZWQgIlVuZGVmaW5lZCIgbWVhbnMgdGhlIG9iamVjdGl2ZSBzY29yZSBmb3IgYm90aCB0ZWFtcyBhcmUgZXF1YWwgc28gdGhlIHJlc3VsdCBvZiB0aGUgbWF0Y2ggZGVwZW5kcyBvbiBvdGhlciBmYWN0b3JzLiBNYXRjaGVzIGxhYmVsZWQgIlVuZXhwZWN0ZWQgbWVhbnMgYSB0ZWFtJ3Mgb2JqZWN0aXZlIHNjb3JlIGlzIGxvd2VyIHRoYW4gdGhlIG90aGVyIHRlYW0gYW5kIHRoZSBmaW5hbCByZXN1bHQgaXMgdGhlIHRlYW0gd2l0aCB0aGUgbG93ZXIgc2NvcmUgd29uLiBPdmVyIDYwJSBvZiB0aGUgbWF0Y2hlcyBpbiBvdmVyIDk4MDAgRGlhbW9uZCByYW5rZWQgZ2FtZXMgc2hvdyB0aGF0IG5vdCBjb21wbGV0aW5nIGFzIG11Y2ggb2JqZWN0aXZlcyBvciBvbmx5IGNvbXBsZXRpbmcgZXF1YWwgYW1vdW50IG9mIG9iamVjdGl2ZXMgYXMgdGhlIGVuZW15IHRlYW0gY2FuIHN0aWxsIHJlc3VsdCBpbiBhIHZpY3RvcnkuIA0KDQpTbyB3aGF0IGRvZXMgYWxsIHRoaXMgZGF0YSBtZWFuIGZvciB0aGUgYXZlcmFnZSBMZWFndWUgb2YgbGVnZW5kcz8NCkluIG9yZGVyIGZvciB5b3UgdG8gaGF2ZSB0aGUgYmVzdCBjaGFuY2UgcG9zc2libGUgdG8gd2luIHRoZSBnYW1lLCBpdCBpcyBleHRyZW1lbHkgaW1wb3J0YW50IHRvIGZhcm0gbWluaW9ucyBhbmQga2lsbCBqdW5nbGUgbW9uc3RlcnMgdG8gaGF2ZSB0aGUgc2FmZXN0IHBhdGggdG93YXJkcyBlYXJuaW5nIHRoZSBtb3N0IGdvbGQgd2l0aG91dCBkeWluZyBieSB0aGUgZW5lbXkgYW5kIHdpbm5pbmcgYSBnYW1lLiANCg0KDQojIyBQcm9mZXNzaW9uYWwgTGVhZ3VlIG9mIExlZ2VuZHMgRXNwb3J0cw0KDQoNCkFzIG1lbnRpb25lZCBiZWZvcmUgdGhlIHJhbmtpbmcgc3lzdGVtIG9mIExlYWd1ZSBvZiBMZWdlbmRzIGhlbHBzIGRldGVybWluZSB0aGUga25vd2xlZGdlIGFuZCBza2lsbCBsZXZlbCBvZiBhIHBsYXllci4gU2luY2UgTGVhZ3VlIG9mIExlZ2VuZHMgaXMgYW4gaW50ZXJuYXRpb25hbCBnYW1lLCBlYWNoIHJlZ2lvbiBvZiB0aGUgd29ybGQgaXMgZGVkaWNhdGVkIGEgc2VydmVyIGZvciB0aGUgcGxheWVycyB0byBwbGF5IG9uLiBFYWNoIHJlZ2lvbmFsIHNlcnZlciByYW5rcyB0aGUgcGxheWVycyB3aXRoIGFjY291bnRzIHNwZWNpZmljYWxseSBkZWRpY2F0ZWQgdG8gdGhhdCBzZXJ2ZXIuIFRoZSBsYXJnZXN0IHNlcnZlcnMgdGhhdCB3aWxsIGRlIGFuYWx5emVkIGlzIE5vcnRoIEFtZXJpY2FuLCBDaGluZXNlLCBLb3JlYW4sIGFuZCBFdXJvcGVhbi4gVGhlIHByb2Zlc3Npb25hbCBsZWFndWVzIG5hbWVkIExDUywgTFBMLCBMQ0ssIGFuZCBMRUMgcmVzcGVjdGl2ZWx5IHRvIGVhY2ggbGFyZ2UgTGVhZ3VlIG9mIExlZ2VuZHMgc2VydmVyLiBFYWNoIHByb2Zlc3Npb25hbCBsZWFndWUgaGF2ZSAxMCB0byAxNyB0ZWFtcyB0aGF0IGNvbXBldGUgd2l0aGluIHRoZWlyIG93biByZWdpb24gZm9yIGEgY2hhbXBpb25zaGlwIHRpdGxlLiBUaGlzIHByb2Zlc3Npb25hbCBzeXN0ZW0gaGFzIHR3byByb3VuZHMgb2YgY29tcGV0aXRpb24gZm9yIGEgcmVnaW9uYWwgdGl0bGUgd2hlcmUgZWFjaCByb3VuZCBpcyBjYWxsZWQgIlNwcmluZyBTcGxpdCIgYW5kICJTdW1tZXIgU3BsaXQiLiBCZWxvdyBpcyB0aGUgb3ZlcmFsbCB3aW5yYXRlIG9mIGVhY2ggdGVhbSBpbiBlYWNoIHJlZ2lvbiBmb3IgYm90aCBTcHJpbmcgYW5kIFN1bW1lciBTcGxpdHMuDQoNCg0KYGBge3IgZWNobyA9IEZBTFNFfQ0KcHJvX2xvbF9yZXZpc2VkIDwtIHByb19sb2xfbWF0Y2hlcyAlPiUgDQogIGZpbHRlcihsZWFndWUgJWluJSBjKCJMUEwiLCAiTENTIiwgIkxDSyIsICJMRUMiKSkgJT4lIA0KICBtdXRhdGUocmVkd2luID0gaWZlbHNlKHJlc3VsdCA9PSAxLCAwLCAxKSkNCg0KcHJvX2xvbF93aW5zIDwtIHRpYmJsZSh0ZWFtID0gYyhwcm9fbG9sX3JldmlzZWQkYmx1ZXRlYW0sIHByb19sb2xfcmV2aXNlZCRyZWR0ZWFtKSwNCiAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gYyhwcm9fbG9sX3JldmlzZWQkcmVzdWx0LCBwcm9fbG9sX3JldmlzZWQkcmVkd2luKSwNCiAgICAgICAgICAgICAgICAgICAgICAgbGVhZ3VlID0gYyhwcm9fbG9sX3JldmlzZWQkbGVhZ3VlLCBwcm9fbG9sX3JldmlzZWQkbGVhZ3VlKSkgJT4lIA0KICBncm91cF9ieShsZWFndWUsIHRlYW0pICU+JSANCiAgc3VtbWFyaXNlKHdpbnJhdGUgPSAoc3VtKHJlc3VsdCkvbigpKSoxMDApICU+JSANCiAgYXJyYW5nZShsZWFndWUsIGRlc2Mod2lucmF0ZSkpICU+JSANCiAgdW5ncm91cCgpDQoNCnByb19sb2xfd2lucyAlPiUgDQogIGdyb3VwX2J5KGxlYWd1ZSkgJT4lIA0KICBzbGljZV9oZWFkKG4gPSAzKSAlPiUgDQogIGdncGxvdChhZXMoeSA9IGxlYWd1ZSwNCiAgICAgICAgICAgeCA9IHdpbnJhdGUsDQogICAgICAgICAgIGNvbG9yID0gZmN0X3Jlb3JkZXIodGVhbSwgd2lucmF0ZSkpKSsNCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIA0KICAgICAgICAgICBwb3NpdGlvbiA9ICdkb2RnZScpKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gdGVhbSksIA0KICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSgwLjkpLCANCiAgICAgICAgICAgIGhqdXN0ID0gMS4xKSsNCiAgdGhlbWVfbWluaW1hbCgpKw0KICBsYWJzKHRpdGxlID0gIlRvcCBXaW5yYXRlcyBvZiBQcm9mZXNzaW9uYWwgTGVhZ3VlIG9mIExlZ2VuZHMgVGVhbXMiLA0KICAgICAgICAgICB4ID0gIlBlcmNlbnQgV2lucmF0ZSIsDQogICAgICAgICAgIHkgPSAiTGVhZ3VlIikrDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikNCiAgDQogIA0KYGBgDQoNCg0KDQpUaGUgbWV0aG9kcyBhbmQgZGF0YSBwcmV2aW91c2x5IHVzZWQgaW4gIldoYXQgaXMgTGVhZ3VlIG9mIExlZ2VuZHM/IiB3YXMgdG8gcHJlZGljdCB0aGUgb3V0Y29tZXMgb2Ygb2Ygbm9uLXByb2Zlc3Npb25hbCBnYW1lcy4gUGxheWVycyBzaWduZWQgdG8gcHJvZmVzc2lvbmFsIExlYWd1ZSBvZiBMZWdlbmRzIHRlYW1zIGFuZCBvcmdhbml6YXRpb25zIGFyZSBleHRyZW1lbHkgaGlnaGVyIHNraWxsZWQgY29tcGFyZSB0byB0aGUgRGlhbW9uZCByYW5rZWQgcGxheWVycy4gQnV0IGRvZXMgdGhlc2UgcGxheWVyJ3Mgc2tpbGwgbGV2ZWwgY2hhbmdlIHRoZSBzYW1lIGNvbmNsdXNpb24gdGhhdCBlYXJuaW5nIHRoZSBtb3N0IGdvbGQgYW5kIG5vdCBjb21wbGV0aW5nIG1vcmUgb2JqZWN0aXZlcyB0aGFuIHRoZSBvcHBvc2luZyB0ZWFtIHN0aWxsIGxlYWQgdG8gYSB2aWN0b3J5Pw0KDQoNCg0KYGBge3IgZWNobyA9IEZBTFNFfQ0KcHJvX2luZGVwdGhfc3RhdHNfZ29sZCA8LSBwcm9faW5kZXB0aF9zdGF0cyAlPiUgDQogIG11dGF0ZSh0MXRvdGFsR29sZCA9IHJvd1N1bXMocHJvX2luZGVwdGhfc3RhdHNbLDE3OjIxXSkpICU+JSANCiAgbXV0YXRlKHQydG90YWxHb2xkID0gcm93U3Vtcyhwcm9faW5kZXB0aF9zdGF0c1ssMjI6MjZdKSkgJT4lIA0KICBtdXRhdGUoZ29sZERpZmYgPSB0MXRvdGFsR29sZCAtIHQydG90YWxHb2xkKSANCg0KcHJvX2luZGVwdGhfc3RhdHNfZ29sZGJsdWUgPC0gcHJvX2luZGVwdGhfc3RhdHNfZ29sZCAlPiUgDQogIGZpbHRlcihnb2xkRGlmZiA+IDApICU+JSANCiAgc3VtbWFyaXNlKHdpbnJhdGUgPSBzdW0odDFfcmVzdWx0L24oKSkqMTAwKQ0KDQpwcm9faW5kZXB0aF9zdGF0c19nb2xkcmVkIDwtIHByb19pbmRlcHRoX3N0YXRzX2dvbGQgJT4lIA0KICBmaWx0ZXIoZ29sZERpZmYgPCAwKSAlPiUgDQogIHN1bW1hcmlzZSh3aW5yYXRlID0gc3VtKHQyX3Jlc3VsdC9uKCkpKjEwMCkNCg0KcHJvX2luZGVwdGhfc3RhdHNfZ29sZHdpbnJhdGUgPC0gdGliYmxlKHRlYW0gPSBjKCJCbHVlIiwgIkJsdWUiLCAiUmVkIiwgIlJlZCIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCAgPSBjKCJ3aW4iLCAibG9zZSIsICJ3aW4iLCAibG9zZSIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpbnJhdGUgPSBhcy5udW1lcmljKGMocHJvX2luZGVwdGhfc3RhdHNfZ29sZGJsdWUsIDEwMC1wcm9faW5kZXB0aF9zdGF0c19nb2xkYmx1ZSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvX2luZGVwdGhfc3RhdHNfZ29sZHJlZCwgMTAwLXByb19pbmRlcHRoX3N0YXRzX2dvbGRyZWQpKSkNCg0KcHJvX2dvbGRkaWZmIDwtIGdncGxvdChwcm9faW5kZXB0aF9zdGF0c19nb2xkd2lucmF0ZSwgYWVzKHggPSB0ZWFtLCB5ID0gd2lucmF0ZSwgZmlsbCA9IHJlc3VsdCkpKw0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSAnZG9kZ2UnKSsNCiAgdGhlbWVfbWluaW1hbCgpKw0KICBzY2FsZV9maWxsX2Rpc2NyZXRlKG5hbWUgPSBOVUxMLA0KICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoIkxvc2UiLCAiV2luIikpKw0KICBsYWJzKHRpdGxlID0gIlByb2Zlc3Npb25hbCBHYW1lcyBcbndpdGggYSBQb3NpdGl2ZSBHb2xkIERpZmZlcmVuY2UiLA0KICAgICAgIHggPSAiIiwNCiAgICAgICB5ICA9ICJQZXJjZW50IFdpbnJhdGVzIikrDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikNCg0Kc29sb3FfZ29sZGRpZmYgKyBwcm9fZ29sZGRpZmYNCmBgYA0KDQoNCkludGVyZXN0aW5nbHksIG9mIHRoZSAxNTAwIHByb2Zlc3Npb25hbCBnYW1lcyBwbGF5ZWQgdGhpcyB5ZWFyIGkgdGhlIGZvdXIgcmVnaW9ucyBvdmVyIDk4JSBwZXJjZW50IG9mIGVhY2ggY29sb3IgdGVhbSB3aXRoIGEgcG9zaXRpdmUgZ29sZCBkaWZmZXJlbnRpYWwgcmVzdWx0ZWQgaW4gYSB2aWN0b3J5IGNvbXBhcmVkIHRvIHRoZSBvbmx5IG92ZXIgNzAlIGluIG5vbi1wcm9mZXNzaW9uYWwgcmFua2VkIGdhbWVzLiBGb3IgdGhlIG5leHQgZmFjdG9ycyB0aGF0IHdhcyBhbmFseXplZCB0byBwcmVkaWN0IHJlc3VsdCBvZiBhIG1hdGNoIGluIGEgbm9uLXByb2Zlc3Npb25hbCBnYW1lLCBvYmplY3RpdmUgc2NvcmVzLCB0aGUgc2FtZSBjYXRlZ29yaWVzIG9mIEhlcmFsZCwgRWxlbWVudGFsIERyYWdvbnMsIEVsZGVyIERyYWdvbiwgQmFyb24gTmFzaG9yLCBhbmQgU3RydWN0dXJlcyBEZXN0cm95ZWQgd2VyZSB1c2VkIHRvIGNhbGN1bGF0ZSBhbmQgb2JqZWN0aXZlIHNjb3JlIGZvciBlYWNoIHRlYW0gaW4gYSBnYW1lLg0KDQoNCg0KYGBge3IgZWNobyA9IEZBTFNFfQ0KcHJvX2luZGVwdGhfc3RhdHNfcmV2aXNlZCA8LSBwcm9faW5kZXB0aF9zdGF0cyAlPiUgDQogIHNlbGVjdChlbmRzX3dpdGgoYygiZHJhZ29ucyIsICJlbGRlcnMiLCAiaGVyYWxkcyIsICJiYXJvbnMiLCAidG93ZXJzIiwgImluaGliaXRvcnMiLCAidG90YWxnb2xkIiwgInJlc3VsdCIpKSkgJT4lIA0KICBtdXRhdGVfYWxsKGFzLm51bWVyaWMpICU+JSANCiAgbmEub21pdCgpDQoNCnByb19vYmpzY29yZSA8LSBwcm9faW5kZXB0aF9zdGF0c19yZXZpc2VkICU+JSANCiAgbXV0YXRlKG9iamVjdGl2ZV9zY29yZV90MSA9IHJvd1N1bXMocHJvX2luZGVwdGhfc3RhdHNfcmV2aXNlZFssIGFzLm51bWVyaWMoYygxLDMsNSw3LDksMTMpKV0pKSAlPiUgDQogIG11dGF0ZShvYmplY3RpdmVfc2NvcmVfdDIgPSByb3dTdW1zKHByb19pbmRlcHRoX3N0YXRzX3JldmlzZWRbLCBhcy5udW1lcmljKGMoMiw0LDYsOCwxMSwxNCkpXSkpICU+JSANCiAgbXV0YXRlKG9ianNjb3JlX2NvbXBhcmUgPSBpZmVsc2UoKG9iamVjdGl2ZV9zY29yZV90MSA+IG9iamVjdGl2ZV9zY29yZV90MikgJiB0MV9yZXN1bHQgPT0xLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkV4cGVjdGVkIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKChvYmplY3RpdmVfc2NvcmVfdDEgPCBvYmplY3RpdmVfc2NvcmVfdDIpICYgdDFfcmVzdWx0ID09IDAsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkV4cGVjdGVkIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShvYmplY3RpdmVfc2NvcmVfdDEgPT0gb2JqZWN0aXZlX3Njb3JlX3QyLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVW5kZWZpbmVkIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlVuZXhwZWN0ZWQiKSkpKQ0KDQpwcm9fb2Jqc2NvcmVfZ3JhcGggPC0gZ2dwbG90KHByb19vYmpzY29yZSwgYWVzKHggPSBvYmpzY29yZV9jb21wYXJlKSkrDQogIGdlb21fYmFyKCkrDQogIGxhYnModGl0bGUgPSAiUHJlZGljdGlvbiBvZiBQcm9mZXNzaW9uYWwgR2FtZXMgXG5HaXZlbiBPYmplY3RpdmUgU2NvcmUiLA0KICAgICAgIHggPSAiIiwNCiAgICAgICB5ID0gIk51bWJlciBvZiBHYW1lcyIpKw0KICB0aGVtZV9taW5pbWFsKCkNCg0Kc29sb3Ffb2Jqc2NvcmUgKyBwcm9fb2Jqc2NvcmVfZ3JhcGgNCmBgYA0KDQoNCkFzIHNlZW4gaW4gdGhlIGNvbXBhcmluZyBiYXIgZ3JhcGggYWJvdmUsIHByb2Zlc3Npb25hbCB0ZWFtcyB3aXRoIGEgaGlnaGVyIG9iamVjdGl2ZSBzY29yZSB3aWxsIGxpa2VseSByZXN1bHQgaW4gYSB2aWN0b3J5LiBUaGlzIHJlc3VsdCBjb250cmFzdCB0aGUgZ2FtZXMgaW4gcmVndWxhciByYW5rZWQgZ2FtZXMuIE92ZXIgOTAlIG9mIHRoZSBnYW1lcyBpbiBwcm9mZXNzaW9uYWwgbGVhZ3VlIHdpdGggaGlnaGVyIG9iamVjdGl2ZSBzY29yZXMgcmVzdWx0IGluIGEgdmljdG9yeSB3aGVyZSBvbmx5IGFib3V0IDQwJSBvZiB0aGUgZ2FtZSBpbiBub24tcHJvZmVzc2lvbmFsIG1hdGNoZXMgd2l0aCBoaWdoZXIgb2JqZWN0aXZlIHNjb3JlcyByZXN1bHRlZCBpbiBhIHZpY3RvcnkuIEEgaGlnaGx5IHBvc3NpYmxlIGV4cGxhbmF0aW9uIGZvciB0aGlzIGlzIGluIHByb2Zlc3Npb25hbCBnYW1lcyB0aGUgcGxheWVycyBvbiB0aGUgc2FtZSB0ZWFtIGNhbiBjb21tdW5pY2F0ZSBhbmQgdGFsayB0byBlYWNoIG90aGVyIHRvIG1ha2UgdGhlIGNvcnJlY3QgcGxheXMgdG8gYWNoaWV2ZSBvYmplY3RpdmVzIHdoaWxlIG5vbi1wcm9mZXNzaW9uYWwgZ2FtZXMgYXJlIHVzdWFsbHkgcGxheWVkIHdpdGggcmFuZG9tIHBsYXllcnMgaW4gdGhlaXIgcmVnaW9uIHRoYXQgdGhleSBtb3N0IGxpa2VseSB3aWxsIG5vdCBrbm93Lg0KDQpCeSBhbmFseXppbmcgYW5kIGRldGVybWluaW5nIHdoaWNoIGZhY3RvcnMgYmVzdCBoZWxwcyB3aW4gYSBtYXRjaCBvZiBsZWFndWUgb2YgbGVnZW5kcywgbmV3ZXIgYW5kIHNtYWxsZXIgdGVhbXMgY2FuIGNvbWUgaW50byB0aGUgYmlnIHNjZW5lIG9mIHByb2Zlc3Npb25hbCBFc3BvcnRzIGFuZCBjcmVhdGUgbW9yZSBjb21wZXRpdGlvbiB0aGF0IHdpbGwgcHVzaCBlYWNoIHRlYW0gdG8gaW5ub3ZhdGUgYW5kIGJlY29tZSBiZXR0ZXIuIA0KDQoNCg0KIyMgV2h5IGlzIHRoaXMgZ2FtZSBpbWFwY3RmdWwgdG8gRXNwb3J0cz8NCg0KDQpBcyB0aGUgNHRoIGxhcmdlc3QgY29tcGV0aXRpdmUgZ2FtZSBpbiB0aGUgd29ybGQsIExlYWd1ZSBvZiBMZWdlbmRzIGluZmx1ZW5jZSBhbmQgZm9sbG93aW5nIGJhc2UgaGFzIHBsYXllZCBhIGh1Z2UgcGFydCBpbiBkZXZlbG9waW5nIHRoZSBFc3BvcnRzIGluZHVzdHJ5LiBCZXNpZGVzIHRoZSBncm93aW5nIG51bWJlciBvZiB0ZWFtcyBvZiBwcm9mZXNzaW9uYWwgYW5kIGV2ZW4gY2FzdWFsIHBsYXllcnMsIExlYWd1ZSBvZiBMZWdlbmRzIGNhbiBpbmZsdWVuY2UgdGhlIGluZHVzdHJ5IHRocm91Z2ggb3RoZXIgd2F5cyBsaWtlIHNvY2lhbCBtZWRpYSBpbmZsdWVuY2VycyBhbmQgc3RyZWFtZXJzIHBsYXkgdGhlIGdhbWUgYW5kIHNwYXJraW5nIHRoZWlyIGZvbGxvd2VycyBpbnRlcmVzdCB0byBqb2luIGEgY29tcGV0aXRpdmUgZ2FtZSBvZiBMZWFndWUgb2YgTGVnZW5kcy4NCg0KDQpgYGB7ciBlY2hvID0gRkFMU0V9DQphbm5vdGF0aW9uIDwtIGRhdGEuZnJhbWUoDQogIHggPSBjKGRteSgwMTAxMjAyMCksIGRteSgwMTAxMjAyMCkpLA0KICB5ID0gYygxNTAsIDIwKSwNCiAgbGFiZWwgPSBjKCJXYXRjaCBUaW1lIiwgIlN0cmVhbSBUaW1lIikNCikNCg0KdHdpdGNoX2xpbmVfZ3JhcGggPC0gIHR3aXRjaF9nYW1lcyAlPiUgDQogIGZpbHRlcihHYW1lID09ICJMZWFndWUgb2YgTGVnZW5kcyIpICU+JSANCiAgZ3JvdXBfYnkoWWVhciwgTW9udGgpICU+JSANCiAgZ2dwbG90KCkrDQogIGdlb21fbGluZShhZXMoeCA9IERhdGUsIA0KICAgICAgICAgICAgIHkgPSBIb3Vyc19TdHJlYW1lZC8xMDAwMDAwKSwNCiAgICAgICAgICAgICBjb2xvciA9ICJibHVlIiwNCiAgICAgICAgICAgIHNpemUgPSAxKSsNCiAgZ2VvbV9saW5lKGFlcyh4ID0gRGF0ZSwgDQogICAgICAgICAgICAgeSA9IEhvdXJzX3dhdGNoZWQvMTAwMDAwMCksDQogICAgICAgICAgICAgY29sb3IgPSAicmVkIiwNCiAgICAgICAgICAgIHNpemUgPSAxKSsNCiAgICBnZW9tX2xhYmVsKGRhdGE9YW5ub3RhdGlvbiwgYWVzKCB4PXgsIHk9eSwgbGFiZWw9bGFiZWwpLA0KICAgICAgICAgICBjb2xvcj0ib3JhbmdlIiwgDQogICAgICAgICAgIHNpemU9NCAsIGFuZ2xlPTQ1LCBmb250ZmFjZT0iYm9sZCIgKSsNCiAgdGhlbWVfbWluaW1hbCgpKw0KICBsYWJzKHRpdGxlID0gIk51bWJlciBvZiBIb3VycyBMZWdhdWUgb2YgTGVnZW5kcyB3YXMgU3RyZWFtZWQvV2F0Y2hlZCBvbiBUd2l0Y2giLA0KICAgICAgIHN1YnRpdGxlID0gIihIdW5kcmVkIG9mIFRob3VzYW5kcyBvZiBIb3VycykiLA0KICAgICAgIHkgPSAiIikNCiAgDQp0d2l0Y2hfbGluZV9ncmFwaCANCmBgYA0KDQoNCg0KT24gb25lIG9mIHRoZSBiaWdnZXN0IHN0cmVhbWluZyBwbGF0Zm9ybXMgaW4gdGhlIHdvcmxkLCBUd2l0Y2gsIExlYWd1ZSBvZiBsZWdlbmRzIGlzIGNvbnNpc3RlbnRseSByYW5rZWQgdGhlIG9uZSBvIHRoZSB0b3AgbW9zdCBzdHJlYW1lZCBhbmQgdmlld2VkIGdhbWVzIGZvciBlYWNoIG1vbnRoIGluIGVhY2ggeWVhciBzaW5jZSAyMDE2IGFzIHNlZW4gaW4gdGhlIHRiYWxlIGJlbG93LiBCZWNhdXNlIHRoZSBDT1ZJRC0xOSBwYW5kZW1pYyBjYXVzZWQgbWFueSB0byBzdGF5IGhvbWUgYW5kIGZpbmQgZW50ZXJ0YWlubWVudCBvbmxpbmUsIHRoZSBncm93dGggb2YgVHdpdGNoIExlYWd1ZSBvZiBMZWdlbmRzIHN0cmVhbSB3YXRjaCB0aW1lcyBoYXZlIGluY3JlYXNlZCBhbG9uZyB3aXRoIHN0cmVhbSB0aW1lLg0KDQoNCg0KYGBge3IgZWNobz1GQUxTRX0NCnR3aXRjaF9nYW1lc19jaGFydCA8LSB0d2l0Y2hfZ2FtZXMgJT4lDQogIGdyb3VwX2J5KFllYXIsIE1vbnRoKSAlPiUgDQogIHNsaWNlX2hlYWQobiA9IDEpICU+JSANCiAgc2VsZWN0KEdhbWUsIFllYXIsIE1vbnRoLCBIb3Vyc19TdHJlYW1lZCxIb3Vyc193YXRjaGVkKSAlPiUgDQogIHVuZ3JvdXAoKSANCg0KZ3RfdGFibGUgPC0gZ3QodHdpdGNoX2dhbWVzX2NoYXJ0KSAlPiUgDQogIHRhYl9oZWFkZXIodGl0bGUgPSAiTW9zdCBQb3B1bGFyIFN0cmVhbWVkIEdhbWVzIG9uIFR3aXRjaCBmb3IgRWFjaCBNb250aCBFYWNoIFllYXIiKSAlPiUgDQogICAgY29sc19sYWJlbCgNCiAgICBIb3Vyc19TdHJlYW1lZCA9ICJIb3VycyBTdHJlYW1lZCIsDQogICAgSG91cnNfd2F0Y2hlZCA9ICJIb3VycyBXYXRjaGVkIg0KICApDQoNCmd0X3RhYmxlDQpgYGANCg0KDQoNCg0KTGVhZ3VlIG9mIExlZ2VuZHMgaGF2ZSBjcmVhdGVkIGEgdW5pcXVlIGNvbW11bml0eSB0aHJvdWdoIGZvbGxvd2luZ3MgZnJvbSBub24tcHJvZmVzc2lvbmFsIHBsYXllcnMsIHByb2Zlc3Npb25hbCB0ZWFtcywgYW5kIHN0cmVhbWVycy9zb2NpYWwgbWVkaWEgaW5mbHVlbmNlcnMgdGhhdCB1bHRpbWF0ZWx5IGhlbHAgc2hhcGUgYW5kIHByb3ZpZGUgZ3Jvd3RoIHRvIHRoZSBsYXJnZSBhbmQgZXhwYW5kaW5nIEVzcG9ydHMgaW5kdXN0cnkuDQoNCg0KIyMgRGF0YSBDb2xsZWN0aW9uDQogDQogDQpUaGUgZGF0YXNldHMgdXNlZCBpbiB0aGlzIHByb2plY3QgbWFqb3JseSBmcm9tIGthZ2dsZS5jb20sIEVzcG9ydHNFYXJuaW5ncy5jb20sIGFuZCBSaW90IEdhbWVzIChDcmVhdG9yIGFuZCBvd25lciBvZiBMZWFndWUgb2YgTGVnZW5kcykuDQpCZWxvdyBhcmUgbGluayB0byB0aGUgd2Vic2l0ZXMgdG8gdGhlIGRhdGEuDQoNCioqRXNwb3J0cyBFYXJuaW5ncyoqDQoNCiAgLSBodHRwczovL3d3dy5rYWdnbGUuY29tL3JhbmtpcnNoL2VzcG9ydHMtZWFybmluZ3MNCiAgLSBVc2VkIHRoZSBzaXRlcyBBUEkgdG8gZ2V0IERhdGEuIEZvciBtb3JlIGluZm9ybWF0aW9uOiBodHRwczovL3d3dy5lc3BvcnRzZWFybmluZ3MuY29tLw0KICANCioqTGVhZ3VlIG9mIExlZ2VuZHMgR2FtZSBTdGF0aXN0aWNzKioNCg0KICBOb24tUHJvZmVzc2lvbmFsIEdhbWVzOiANCiAgICAtIGh0dHBzOi8vd3d3LmthZ2dsZS5jb20vYm9iYnlzY2llbmNlL2xlYWd1ZS1vZi1sZWdlbmRzLWRpYW1vbmQtcmFua2VkLWdhbWVzLTEwLW1pbg0KICAgIA0KICBQcm9mZXNzaW9uYWw6DQogICAgLSBodHRwczovL3d3dy5rYWdnbGUuY29tL3htb3JyYS9sb2wyMDIwZXNwb3J0cz9zZWxlY3Q9bWF0Y2hlczIwMjAuY3N2DQogICAgLSBodHRwczovL3d3dy5rYWdnbGUuY29tL2Zlcm5hbmRvcnViaW9nYXJjaWEvMjAyMC1sZWFndWUtb2YtbGVnZW5kcy1jb21wZXRpdGl2ZS1nYW1lcw0KICAgIA0KKipTdHJlYW1zIC0gVHdpdGNoKioNCg0KICAtIGh0dHBzOi8vd3d3LmthZ2dsZS5jb20vcmFua2lyc2gvZXZvbHV0aW9uLW9mLXRvcC1nYW1lcy1vbi10d2l0Y2g=